package com.tyylab.kestrel.framework.core.annoutil;

import net.bytebuddy.description.annotation.AnnotationDescription;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * Spring Core Annotation Util for ByteBuddy.
 * @author tyylab
 */
public class SpringCoreAnnotationUtil {
    /**
     * Create a {@link Configuration} annotation.
     * See {@link Configuration}
     * @param name
     * @return AnnotationDescription
     */
    public static AnnotationDescription configuration(String name) {
        return AnnotationDescription.Builder.ofType(Configuration.class)
                .define("value", StringUtils.hasText(name) ? name : "")
                .build();
    }

    /**
     * Create a {@link Autowired} annotation.
     * See {@link Autowired}
     * @param required
     * @return
     */
    public static AnnotationDescription autowired(boolean required) {
        return AnnotationDescription.Builder.ofType(Autowired.class)
                .define("required", required)
                .build();
    }

    /**
     * Create a {@link Qualifier} annotation.
     * See {@link Qualifier}
     * @param name
     * @return
     */
    public static AnnotationDescription qualifier(String name) {
        return AnnotationDescription.Builder.ofType(Qualifier.class)
                .define("value", StringUtils.hasText(name) ? name : "")
                .build();
    }

    /**
     * Create a {@link Lazy} annotation
     * @param lazy
     * @return
     */
    public static AnnotationDescription lazy(boolean lazy) {
        return AnnotationDescription.Builder.ofType(Lazy.class)
                .define("value", lazy)
                .build();
    }

    /**
     * Create a {@link Bean} annotation
     * @param name
     * @param initMethod
     * @param destroyMethod
     * @param autowireCandidate
     * @return
     */
    public static AnnotationDescription bean(String[] name, String initMethod, String destroyMethod,
                                                  boolean autowireCandidate) {
        return AnnotationDescription.Builder.ofType(Bean.class)
                .defineArray("value", ArrayUtils.isEmpty(name) ? new String[] {} : name)
                .defineArray("name", ArrayUtils.isEmpty(name) ? new String[] {} : name)
                .define("initMethod", StringUtils.hasText(initMethod) ? initMethod : "")
                .define("destroyMethod", StringUtils.hasText(destroyMethod) ? destroyMethod : "")
                .define("autowireCandidate", autowireCandidate)
                .build();
    }

    /**
     * Create a {@link Scope} annotation
     * @param scopeName
     * @param proxyMode
     * @return
     */
    public static AnnotationDescription scope(String scopeName, ScopedProxyMode proxyMode) {
        return AnnotationDescription.Builder.ofType(Scope.class)
                .defineArray("value", StringUtils.hasText(scopeName) ? scopeName : "")
                .defineArray("scopeName", StringUtils.hasText(scopeName) ? scopeName : "")
                .define("proxyMode", proxyMode != null ? proxyMode : ScopedProxyMode.DEFAULT)
                .build();
    }

    public static AnnotationDescription service(String value) {
        return AnnotationDescription.Builder.ofType(Service.class)
                .define("value", StringUtils.hasText(value) ? value:"")
                .build();
    }

    public static AnnotationDescription component(String value) {
        return AnnotationDescription.Builder.ofType(Component.class)
                .define("value", StringUtils.hasText(value) ? value:"")
                .build();
    }
}
